package com.hzgj.bcl.soa.rpc.message;

import com.hzgj.bcl.soa.api.IdempotentIdGen;
import com.hzgj.bcl.soa.rpc.RpcContext;
import com.hzgj.bcl.soa.rpc.client.RequestOptions;
import com.hzgj.bcl.soa.spi.MessageHandleFactory;
import com.hzgj.bcl.soa.util.Constants;
import com.hzgj.bcl.util.lang.StrKit;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * Created by warning on 2016/11/4.
 */
public class DefaultMessageHandleFactory implements MessageHandleFactory {
    @Override
    public Message buildRequestMessage(Method method, Object[] args, RequestOptions options) {
        MethodCall method_call = new MethodCall(method.getName(), args);
        method_call.setService(options.getReferenceDef().getService());
        method_call.setContextId(RpcContext.getContextId());
        if (StrKit.isBlank(RpcContext.getWhoIm())) {
            method_call.setClientName(options.getSource());
        } else {
            method_call.setClientName(RpcContext.getWhoIm());
        }
        if (options.getMethodDef() != null) {
            IdempotentIdGen idempotentIdGen = options.getMethodDef().getIdempotentIdGen();
            if (idempotentIdGen != null) {
                String continueId = idempotentIdGen.getContinueId();
                if (StrKit.isBlank(continueId)) {
                    throw new RuntimeException("idempotentIdGen exist,but continueId is null");
                } else {
                    method_call.setBizId(continueId);
                }
            }
        }
        return new Message(method_call);
    }

    @Override
    public Message buildResponse(Long req_id, Object reply, boolean is_exception) {
        return new Message(reply);
    }

    @Override
    public Message buildErrorResponse(Throwable throwable, Map<String, Object> headers) {
        return new Message().setPayload(throwable).putHeaders(headers).putHeader(Constants.MESSAGE_TYPE, Message.EXC_RSP);
    }

    @Override
    public <T> T handleResponse(Object response) throws Exception {
        return (T) response;
    }

    @Override
    public String getName() {
        return Constants.DEFAULT_PROTOCOL;
    }
}
